package report

import (
	"../common"
	"../web"
	"encoding/json"
	"regexp"
	"strconv"
	"strings"
	"time"
)

type QueryDailyObj struct {
	common.BaseHandler
}

type QueryDailyDetailObj struct {
	common.BaseHandler
}

type QueryDailyPageObj struct {
	common.BaseHandler
}

func (self *QueryDailyObj) Prepare() {
	items := *common.FetchAllRowsPtr(
		`SELECT ITEM, ISNULL(DESCRIP, '') 
           FROM SFC_ITEMS(NOLOCK) 
          WHERE LOCKED = 0 
          ORDER BY ITEM`,
		self.Usr.Conn, new(common.ItemDesc))

	self.TmplData["items"] = items
}

func (self *QueryDailyObj) ParameterCheck() bool {
	date_pattern, _ := regexp.Compile(`^(\d{4}-\d{2}-\d{2})`)
	s_date := strings.TrimSpace(self.Ctx.Params["fromdate"])
	c_item := self.Ctx.Params["item"]
	if s_date == "" {
		return false
	}
	p_date, err := time.Parse("2006-01-02 15:04:05", s_date)
	if err != nil {
		self.TmplData["error"] = common.GetText(self.Lang, "Query Date is invalid.")
		return false
	}
	if len(s_date) != 19 {
		self.TmplData["error"] = common.GetText(self.Lang, "Query Date is invalid.")
		return false
	}
	s_date = p_date.Format("2006-01-02 15:04:05")
	t := date_pattern.FindStringSubmatch(s_date)
	c_date, _ := time.Parse("2006-01-02", t[1])
	end_date := c_date.Add(3600 * 24 * time.Second)
	s_end := end_date.Format("2006-01-02 15:04:05")

	self.Sqlparas = append(self.Sqlparas, s_date)
	self.Sqlparas = append(self.Sqlparas, s_end)
	self.Sqlparas = append(self.Sqlparas, c_item)

	return true
}

func (self *QueryDailyObj) SqlQueryExecute() {
	s_date := self.Sqlparas[0].(string)
	s_end := self.Sqlparas[1].(string)
	c_item := self.Sqlparas[2].(string)
	var dl_ls []*common.DailyResult
	var dailydata []interface{}
	if c_item != "" {
		dailydata = *common.FetchAllRowsPtr(
			`SELECT A.CURR_STATION, A.RESULT, A.HOURRANGE, COUNT(A.SSN_NO) 
           	   FROM SFC_SSNFLOW A(NOLOCK), SFC_SSN B(NOLOCK), SFC_WO C(NOLOCK) 
          	  WHERE A.MODIFYDATE BETWEEN ? AND ? 
            	AND A.SSN_NO=B.SSN_NO 
            	AND B.WONO=C.WONO 
            	AND C.ITEM=? 
          	  GROUP BY A.CURR_STATION, A.RESULT, A.HOURRANGE`,
			self.Usr.Conn, new(common.DailyQuery), s_date, s_end, c_item)
	} else {
		c_item = "All"
		dailydata = *common.FetchAllRowsPtr(
			`SELECT CURR_STATION, RESULT, HOURRANGE, COUNT(SSN_NO) 
		   	   FROM SFC_SSNFLOW(NOLOCK) 
		  	  WHERE MODIFYDATE BETWEEN ? AND ? 
		  	  GROUP BY CURR_STATION, RESULT, HOURRANGE`,
			self.Usr.Conn, new(common.DailyQuery), s_date, s_end)
	}

	dict_total := &common.DailyResult{"Total", c_item, s_date, s_end,
		[25]*common.DailyDetails{
			{"00:00 - 01:00", 0, 0, "0.0"},
			{"01:00 - 02:00", 0, 0, "0.0"},
			{"02:00 - 03:00", 0, 0, "0.0"},
			{"03:00 - 04:00", 0, 0, "0.0"},
			{"04:00 - 05:00", 0, 0, "0.0"},
			{"05:00 - 06:00", 0, 0, "0.0"},
			{"06:00 - 07:00", 0, 0, "0.0"},
			{"07:00 - 08:00", 0, 0, "0.0"},
			{"08:00 - 09:00", 0, 0, "0.0"},
			{"09:00 - 10:00", 0, 0, "0.0"},
			{"10:00 - 11:00", 0, 0, "0.0"},
			{"11:00 - 12:00", 0, 0, "0.0"},
			{"12:00 - 13:00", 0, 0, "0.0"},
			{"13:00 - 14:00", 0, 0, "0.0"},
			{"14:00 - 15:00", 0, 0, "0.0"},
			{"15:00 - 16:00", 0, 0, "0.0"},
			{"16:00 - 17:00", 0, 0, "0.0"},
			{"17:00 - 18:00", 0, 0, "0.0"},
			{"18:00 - 19:00", 0, 0, "0.0"},
			{"19:00 - 20:00", 0, 0, "0.0"},
			{"20:00 - 21:00", 0, 0, "0.0"},
			{"21:00 - 22:00", 0, 0, "0.0"},
			{"22:00 - 23:00", 0, 0, "0.0"},
			{"23:00 - 00:00", 0, 0, "0.0"},
			{"Subtotal", 0, 0, "0.0"},
		},
	}

	for _, val := range dailydata {
		s_stat := strings.TrimSpace(val.(common.DailyQuery).Station)
		s_rslt := strings.TrimSpace(val.(common.DailyQuery).Result)
		s_hour := strings.TrimSpace(val.(common.DailyQuery).Hourrange)
		s_totl := val.(common.DailyQuery).Count
		flags := false
		for _, v := range dl_ls {
			if v.Station == s_stat {
				flags = true
				break
			}
		}
		if !flags {
			dl_ls = append(dl_ls, &common.DailyResult{s_stat, c_item, s_date, s_end,
				[25]*common.DailyDetails{
					{"00:00 - 01:00", 0, 0, "0.0"},
					{"01:00 - 02:00", 0, 0, "0.0"},
					{"02:00 - 03:00", 0, 0, "0.0"},
					{"03:00 - 04:00", 0, 0, "0.0"},
					{"04:00 - 05:00", 0, 0, "0.0"},
					{"05:00 - 06:00", 0, 0, "0.0"},
					{"06:00 - 07:00", 0, 0, "0.0"},
					{"07:00 - 08:00", 0, 0, "0.0"},
					{"08:00 - 09:00", 0, 0, "0.0"},
					{"09:00 - 10:00", 0, 0, "0.0"},
					{"10:00 - 11:00", 0, 0, "0.0"},
					{"11:00 - 12:00", 0, 0, "0.0"},
					{"12:00 - 13:00", 0, 0, "0.0"},
					{"13:00 - 14:00", 0, 0, "0.0"},
					{"14:00 - 15:00", 0, 0, "0.0"},
					{"15:00 - 16:00", 0, 0, "0.0"},
					{"16:00 - 17:00", 0, 0, "0.0"},
					{"17:00 - 18:00", 0, 0, "0.0"},
					{"18:00 - 19:00", 0, 0, "0.0"},
					{"19:00 - 20:00", 0, 0, "0.0"},
					{"20:00 - 21:00", 0, 0, "0.0"},
					{"21:00 - 22:00", 0, 0, "0.0"},
					{"22:00 - 23:00", 0, 0, "0.0"},
					{"23:00 - 00:00", 0, 0, "0.0"},
					{"Subtotal", 0, 0, "0.0"},
				},
			})
		}
		for _, v := range dl_ls {
			if v.Station != s_stat {
				continue
			}
			for i, dv := range v.Details {
				if i == 24 {
					if s_rslt == "PASS" {
						dv.ValPass = dv.ValPass + s_totl
					}
					if s_rslt == "FAIL" {
						dv.ValFail = dv.ValFail + s_totl
					}
					continue
				}
				if dv.Hours != s_hour {
					continue
				}
				if s_rslt == "PASS" {
					dv.ValPass = s_totl
				}
				if s_rslt == "FAIL" {
					dv.ValFail = s_totl
				}
			}
		}
	}

	for _, v := range dl_ls {
		for _, val := range v.Details {
			for _, dv := range dict_total.Details {
				if val.Hours != dv.Hours {
					continue
				}
				dv.ValPass = dv.ValPass + val.ValPass
				dv.ValFail = dv.ValFail + val.ValFail
			}
		}
	}

	dl_ls = append(dl_ls, dict_total)

	f_py := 100.0
	for _, v := range dl_ls {
		for _, val := range v.Details {
			i_v1 := val.ValPass
			i_v2 := val.ValFail
			i_total := i_v1 + i_v2
			i_pass := i_v1
			if i_pass == 0 {
				f_py = 0.0
			} else if i_total > 0 {
				f_py = float64(i_pass) * 1.0 / float64(i_total) * 100.0
			}
			val.PassYield = strconv.FormatFloat(f_py, 'f', 1, 64)
			if f_py > 0.0 && f_py < 100.0 {
				val.PassYield = strconv.FormatFloat(f_py, 'f', 2, 64)
			}
		}
	}

	var tableHead [][3]string
	for i := 0; i < 25; i++ {
		tableHead = append(tableHead, [3]string{"PASS", "FAIL", "PY"})
	}

	self.TmplData["from_datetime"] = s_date
	self.TmplData["to_datetime"] = s_end
	self.TmplData["item"] = c_item
	self.TmplData["dl_ls"] = dl_ls
	self.TmplData["tableHead"] = tableHead
}

func DailyRprHandler(ctx *web.Context) {
	self := new(QueryDailyObj)
	self.Ctx = ctx
	self.Html = "dailyreport.html"
	self.Rightlist = []string{"dailyreport"}
	self.DoQuery(self)
}

func (self *QueryDailyDetailObj) ParameterCheck() bool {
	s_nm := self.Ctx.Params["nm"] // query result data number
	s_fd := self.Ctx.Params["fd"] // begin date
	s_td := self.Ctx.Params["td"] // end date
	s_im := self.Ctx.Params["im"] // item
	s_st := self.Ctx.Params["st"] // station
	s_ho := self.Ctx.Params["ho"] // hour range
	s_ts := self.Ctx.Params["ts"] // PASS/FAIL
	if s_nm == "" || s_fd == "" || s_td == "" || s_im == "" ||
		s_st == "" || s_ho == "" || s_ts == "" {
		return false
	}

	self.Sqlparas = append(self.Sqlparas, s_fd)
	self.Sqlparas = append(self.Sqlparas, s_td)
	self.Sqlparas = append(self.Sqlparas, s_im)
	self.Sqlparas = append(self.Sqlparas, s_st)
	self.Sqlparas = append(self.Sqlparas, s_ho)
	self.Sqlparas = append(self.Sqlparas, s_ts)

	rec_curr, _ := strconv.Atoi(s_nm)
	total_id := rec_curr / 10
	if rec_curr%10 > 0 {
		total_id++
	}
	self.TmplData["total_page"] = total_id
	self.TmplData["fromdate"] = s_fd
	self.TmplData["todate"] = s_td
	self.TmplData["item"] = s_im
	self.TmplData["station"] = s_st
	self.TmplData["hourrange"] = s_ho
	self.TmplData["status"] = s_ts

	return true
}

func (self *QueryDailyDetailObj) SqlQueryExecute() {
	ssn_main := *common.FetchAllRowsPtr(
		`sp_QueryDailyDetails ?, ?, ?, ?, ?, ?`,
		self.Usr.Conn, new(common.QueryDetail), self.Sqlparas...)

	self.TmplData["ssn_main"] = ssn_main
	self.TmplData["curr_page"] = "1"
}

func DailyDetailHandler(ctx *web.Context) {
	self := new(QueryDailyDetailObj)
	self.Ctx = ctx
	self.Html = "dailydetail.html"
	self.Rightlist = []string{"dailyreport"}
	self.DoQueryUrl(self)
}

func (self *QueryDailyPageObj) ParameterCheck() bool {
	pageid := self.Ctx.Params["pageid"] // current page
	s_fd := self.Ctx.Params["fd"]       // begin date
	s_td := self.Ctx.Params["td"]       // end date
	s_im := self.Ctx.Params["im"]       // item
	s_st := self.Ctx.Params["st"]       // station
	s_ho := self.Ctx.Params["ho"]       // hour range
	s_ts := self.Ctx.Params["ts"]       // PASS/FAIL

	s_id, err := strconv.Atoi(pageid)
	if err != nil {
		return false
	}
	if s_fd == "" || s_td == "" || s_im == "" || s_st == "" ||
		s_ho == "" || s_ts == "" {
		return false
	}

	idx := 10 * (s_id - 1)

	self.Sqlparas = append(self.Sqlparas, s_fd)
	self.Sqlparas = append(self.Sqlparas, s_td)
	self.Sqlparas = append(self.Sqlparas, s_im)
	self.Sqlparas = append(self.Sqlparas, s_st)
	self.Sqlparas = append(self.Sqlparas, s_ho)
	self.Sqlparas = append(self.Sqlparas, s_ts)
	self.Sqlparas = append(self.Sqlparas, idx)

	return true
}

func (self *QueryDailyPageObj) SqlQueryExecute() {
	ssn_main := *common.FetchAllRowsPtr(
		`sp_QueryDailyPerPageDetails ?, ?, ?, ?, ?, ?, ?`,
		self.Usr.Conn, new(common.QueryDetail), self.Sqlparas...)

	dict_js, _ := json.Marshal(map[string]interface{}{"dailys": ssn_main, "lang": self.Lang})
	self.Ctx.ResponseWriter.Write(dict_js)
}

func SplitDailyByPageHandler(ctx *web.Context) {
	self := new(QueryDailyPageObj)
	self.Ctx = ctx
	self.DoJsonQuery(self)
}
